
package capturador;

import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.media.Buffer;
import javax.media.CannotRealizeException;
import javax.media.CaptureDeviceManager;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoPlayerException;
import javax.media.Player;
import javax.media.control.FrameGrabbingControl;
import javax.media.format.VideoFormat;
import javax.media.util.BufferToImage;
import javax.swing.Timer;

/**
 *
 * @author Alejandro D. Villalba
 */
public class PantallaBase extends javax.swing.JFrame {

    //Atributos necesarios para el JMF
    private static Player player = null;
    private MediaLocator localizador = null;
    //Variables del Timer
    private Timer timer;
    private int fps=1; //1 milisegundo
    private Buffer buffer;
    private Image img = null;
    private BufferToImage buffer_image = null;


    public PantallaBase() {
        initComponents();
        
        //lista de dispositivos en un combobox
        if (CaptureDeviceManager.getDeviceList(null).isEmpty())
        {
            jopMensaje.showMessageDialog(null,"No se Detectaron Dispositivos");
        }
        else 
        {
            for (int i = 0; i < CaptureDeviceManager.getDeviceList(null).size(); i++) {
                this.jcLocator.addItem(CaptureDeviceManager.getDeviceList(null).get(i));    
            }
        }
        //La frecuencia de refresco
        this.txtfps.setText("100");
        //Se actualiza el valor del umbral en el label
        this.lblUmbral.setText(String.valueOf(this.jsUmbral.getValue()));
        this.setFps(Integer.valueOf(this.txtfps.getText()));
        this.iniciarTemporizador();
    }

    /**
     * Se instanciará una clase Timer cuya tarea será la de capturar la señal
     * de video cada cierto tiempo definido por el usuario.
     * Cada vez que se ejecute, se llamarán a los procesos de actualización de los paneles de video
     */
    public void iniciarTemporizador()
    {
        try {
            timer = new Timer (this.getFps(), new ActionListener () {   //Cada FPS milisegundo capturará el frame de video
            public void actionPerformed(ActionEvent e) {
                FrameGrabbingControl fgc = (FrameGrabbingControl)player.getControl("javax.media.control.FrameGrabbingControl");
                buffer = fgc.grabFrame();
                // Convert it to an image
                buffer_image = new BufferToImage((VideoFormat)buffer.getFormat());
                img = buffer_image.createImage(buffer);
                //Se actualiza el panel de la imagen original
                pnlGrises.setImage(img);
                //Se actualiza el panel binarizado
                pnlLienzoUmbralizado.setUmbral(jsUmbral.getValue());
                pnlLienzoUmbralizado.setLienzoOriginal(pnlGrises);
            }
        });
        } catch (Exception e) {
            jopMensaje.showMessageDialog(null,e.toString());
        }
    }
    
    /**
     * Se encarga de crear los Realized Player utilizando un MediaLocator instanciado en el constructor
     */
    private void iniciarCaptura() {
        try {
            //Se crea un player
            player = Manager.createRealizedPlayer(localizador);
            //Se inicializa el player
            player.start();
        } catch (IOException e) {
            System.err.println(e.toString());
            jopMensaje.showMessageDialog(null,e.toString());
        } catch (CannotRealizeException e) {
            System.err.println(e.toString());
            jopMensaje.showMessageDialog(null,e.toString());
        } catch (NoPlayerException e) {
            System.err.println(e.toString());
            jopMensaje.showMessageDialog(null,e.toString());
        }
    }

    public void acceso2Frames() {
        timer.start();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jopMensaje = new javax.swing.JOptionPane();
        pnlGrises = new capturador.LienzoOriginal();
        botonCapturar = new javax.swing.JButton();
        botonSalir = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        txtfps = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jsUmbral = new javax.swing.JSlider();
        lblUmbral = new javax.swing.JLabel();
        pnlLienzoUmbralizado = new capturador.LienzoUmbralizado();
        jcLocator = new javax.swing.JComboBox();
        jScrollPane1 = new javax.swing.JScrollPane();
        txtaDetalleLocator = new javax.swing.JTextArea();
        jLabel5 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        txtSource = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Umbralizacion de Video");
        setResizable(false);

        pnlGrises.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        pnlGrises.setPreferredSize(new java.awt.Dimension(300, 300));

        javax.swing.GroupLayout pnlGrisesLayout = new javax.swing.GroupLayout(pnlGrises);
        pnlGrises.setLayout(pnlGrisesLayout);
        pnlGrisesLayout.setHorizontalGroup(
            pnlGrisesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 298, Short.MAX_VALUE)
        );
        pnlGrisesLayout.setVerticalGroup(
            pnlGrisesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 298, Short.MAX_VALUE)
        );

        botonCapturar.setText("Iniciar");
        botonCapturar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botonCapturarActionPerformed(evt);
            }
        });

        botonSalir.setText("Salir");
        botonSalir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botonSalirActionPerformed(evt);
            }
        });

        jLabel1.setText("Frecuencia (milisegundos):");

        jLabel2.setText("Locator:");

        jLabel3.setText("Original Grises");

        jLabel4.setText("Umbralizado");

        jsUmbral.setMaximum(254);
        jsUmbral.setValue(127);
        jsUmbral.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jsUmbralStateChanged(evt);
            }
        });

        lblUmbral.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        pnlLienzoUmbralizado.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        pnlLienzoUmbralizado.setPreferredSize(new java.awt.Dimension(300, 300));

        javax.swing.GroupLayout pnlLienzoUmbralizadoLayout = new javax.swing.GroupLayout(pnlLienzoUmbralizado);
        pnlLienzoUmbralizado.setLayout(pnlLienzoUmbralizadoLayout);
        pnlLienzoUmbralizadoLayout.setHorizontalGroup(
            pnlLienzoUmbralizadoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
        pnlLienzoUmbralizadoLayout.setVerticalGroup(
            pnlLienzoUmbralizadoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 298, Short.MAX_VALUE)
        );

        jcLocator.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
        jcLocator.setMaximumSize(new java.awt.Dimension(27, 19));
        jcLocator.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                jcLocatorItemStateChanged(evt);
            }
        });

        txtaDetalleLocator.setColumns(20);
        txtaDetalleLocator.setRows(5);
        txtaDetalleLocator.setMaximumSize(new java.awt.Dimension(200, 15));
        jScrollPane1.setViewportView(txtaDetalleLocator);

        jLabel5.setText("Detalle Locator:");

        jLabel7.setText("Source:");

        jLabel8.setText("Defecto  (vfw://0)");

        txtSource.setText("vfw://0");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(111, 111, 111)
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jLabel4)
                        .addGap(142, 142, 142))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(20, 20, 20)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(jLabel1)
                                    .addComponent(jLabel5)
                                    .addComponent(jLabel2)))
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addContainerGap()
                                .addComponent(jLabel7)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel8)
                                    .addComponent(txtSource, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE))))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(txtfps, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(0, 0, Short.MAX_VALUE))
                            .addComponent(jcLocator, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING)))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(pnlGrises, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(botonCapturar)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(botonSalir)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jsUmbral, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(lblUmbral, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(pnlLienzoUmbralizado, javax.swing.GroupLayout.PREFERRED_SIZE, 302, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(txtfps, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jcLocator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel5)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(txtSource, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel7))))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel8)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jsUmbral, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblUmbral, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(botonSalir)
                        .addComponent(botonCapturar)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pnlLienzoUmbralizado, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(pnlGrises, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void botonSalirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_botonSalirActionPerformed
        // Se detiene la visualización
        if(player != null) {
            player.close();
            player.deallocate();
        }
        this.txtfps.setEnabled(true);
        this.txtSource.setEnabled(true);
        timer.stop();
        //System.exit(0);
    }//GEN-LAST:event_botonSalirActionPerformed

    private void botonCapturarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_botonCapturarActionPerformed
        //se inicializa la visualización
        if(!this.txtfps.getText().isEmpty())
        {
            try {
                //Se instancia el Locator en función del identificador de dispositivo
                localizador = new MediaLocator(this.txtSource.getText());
                this.txtfps.setEnabled(false);
                this.txtSource.setEnabled(false);
                timer.start();  
                iniciarCaptura();
            } catch (Exception e) {
                jopMensaje.showMessageDialog(null, e.getMessage());
            }
        }
    }//GEN-LAST:event_botonCapturarActionPerformed

    private void jsUmbralStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jsUmbralStateChanged
        // Se seleccionó otro valor de umbral
        this.lblUmbral.setText(String.valueOf(this.jsUmbral.getValue()));
    }//GEN-LAST:event_jsUmbralStateChanged

    private void jcLocatorItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jcLocatorItemStateChanged
        this.txtaDetalleLocator.setText(this.jcLocator.getSelectedItem().toString());
    }//GEN-LAST:event_jcLocatorItemStateChanged

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                setDefaultLookAndFeelDecorated(true);
                PantallaBase ventana = new PantallaBase();
                ventana.setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton botonCapturar;
    private javax.swing.JButton botonSalir;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JComboBox jcLocator;
    private javax.swing.JOptionPane jopMensaje;
    private javax.swing.JSlider jsUmbral;
    private javax.swing.JLabel lblUmbral;
    private capturador.LienzoOriginal pnlGrises;
    private capturador.LienzoUmbralizado pnlLienzoUmbralizado;
    private javax.swing.JTextField txtSource;
    private javax.swing.JTextArea txtaDetalleLocator;
    private javax.swing.JTextField txtfps;
    // End of variables declaration//GEN-END:variables

    /**
     * @return the fps
     */
    public int getFps() {
        return fps;
    }

    /**
     * @param fps the fps to set
     */
    public void setFps(int fps) {
        this.fps = fps;
    }

}
